////////////////////////////////////////////////////////////////////////////////////////
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING THIS SOFTWARE
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install, copy or use the software.
//
// Copyright (C) 2013, AerVision Technologies Pty Ltd, all rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of AerVision Technologies, may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors to demonstrate 
// www.AerCloud.net Framework as a Service API (FaaS), "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the copyright holder or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
////////////////////////////////////////////////////////////////////////////////////////

package com.aercloud.client.gui;

import java.awt.Cursor;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.apache.log4j.Logger;

import com.aercloud.client.util.AerCloudClient;

public class PanelStep4 extends JPanel {
    
    private static Logger log = Logger.getLogger(PanelStep4.class);
    
    private File dbDir;
    private BufferedImage currentImage;
    private boolean searchInProgress;
    private JFrame frame;
    
    private JLabel lblImage;
    private JScrollPane scrollPaneImage;
    private PanelStep4List panelList;

    /**
     * Create the panel.
     */
    public PanelStep4() {
        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0};
        gridBagLayout.rowHeights = new int[]{0};
        gridBagLayout.columnWeights = new double[]{1.0, 1.0, 1.0, 1.0, 1.0};
        gridBagLayout.rowWeights = new double[]{1.0};
        setLayout(gridBagLayout);
        GridBagConstraints gbc_panelList = new GridBagConstraints();
        gbc_panelList.fill = GridBagConstraints.BOTH;
        gbc_panelList.gridx = 0;
        gbc_panelList.gridy = 0;
        add(getPanelList(), gbc_panelList);
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    dbDir = new File(Thread.currentThread().getContextClassLoader().getResource("Query").toURI());
                    if(dbDir.exists() && dbDir.isDirectory() && dbDir.canRead()) {
                        getPanelList().getList().setListData(dbDir.list(new FilenameFilterImage()));
                    }
                    PanelStep4.this.getPanelList().getBtnSearch().getAction().setEnabled(getPanelList().getList().getModel().getSize() > 0);
                } catch(Exception e) {
                    log.debug("Failed to locate Query directory", e);
                }
            }
        });
        getPanelList().getList().addListSelectionListener(new ListSelectionListener(){
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if(!e.getValueIsAdjusting()) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                PanelStep4.this.currentImage =
                                    ImageIO.read(new File(dbDir,(String)getPanelList().getList().getSelectedValue()));
                                getLblImage().setIcon(
                                    new ImageIcon(PanelStep4.this.currentImage));
                            } catch (Exception e) {
                                log.debug("Failed to load an image", e);
                            }
                        }
                    });
                }
            }
        });
        GridBagConstraints gbc_scrollPaneImage = new GridBagConstraints();
        gbc_scrollPaneImage.gridwidth = 4;
        gbc_scrollPaneImage.fill = GridBagConstraints.BOTH;
        gbc_scrollPaneImage.gridx = 1;
        gbc_scrollPaneImage.gridy = 0;
        add(getLblImage(), gbc_scrollPaneImage);
    }
    
    public void setFrame(JFrame frame) {
        this.frame = frame;
    }
    
    public void search(final AerCloudClient aerCloudClient, final String accessKey) {
        if(currentImage != null && !searchInProgress) {
            aerCloudClient.getExecPool().submit(new Runnable() {
                @Override
                public void run() {
                    PanelStep4.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                    searchInProgress = true;
                    int index = 1;
                    String selectedImageName = (String)getPanelList().getList().getSelectedValue();
                    Point origin = new Point(100, 100);
                    if(frame != null) {
                        origin.x = frame.getBounds().x + 25;
                        origin.y = frame.getBounds().y + 25;
                    }
                    for(BufferedImage bufferedImage : aerCloudClient.detectFaces(accessKey, selectedImageName, currentImage)) {
                        FrameSearchResultsBrowser searchResultBrowser =
                            new FrameSearchResultsBrowser();
                        Rectangle bounds = searchResultBrowser.getBounds();
                        bounds.x = origin.x;
                        bounds.y = origin.y;
                        searchResultBrowser.setBounds(bounds);
                        searchResultBrowser.setVisible(true);
                        searchResultBrowser.getPanelSearchResultsBrowserContentPane().getPanelSearchResultsBrowser()
                            .search(aerCloudClient, accessKey, selectedImageName + "[" + index + "]", bufferedImage);
                        index++;
                        origin.x += 25;
                        origin.y += 25;
                    }
                    searchInProgress = false;
                    PanelStep4.this.setCursor(Cursor.getDefaultCursor());
                }
            });
        }
    }
    
    @Override
    public void setCursor(Cursor paramCursor) {
        if(frame != null) {
            frame.setCursor(paramCursor);
        } else {
            super.setCursor(paramCursor);
        }
    }
    
    public JLabel getLblImage() {
        if (lblImage == null) {
        	lblImage = new LabelImage();
        	lblImage.setVerticalAlignment(SwingConstants.TOP);
        }
        return lblImage;
    }
    private JScrollPane getScrollPaneImage() {
        if (scrollPaneImage == null) {
        	scrollPaneImage = new JScrollPane();
        	scrollPaneImage.setViewportView(getLblImage());
        }
        return scrollPaneImage;
    }
    public PanelStep4List getPanelList() {
        if (panelList == null) {
        	panelList = new PanelStep4List();
        }
        return panelList;
    }
}
